package test.shadow;

import android.app.PendingIntent;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;

import java.util.List;

import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;

import test.util.Log;

@Implements(BluetoothLeScanner.class)
public class MyShadowBluetoothLeScanner {
    private static final String TAG = MyShadowBluetoothLeScanner.class.getSimpleName();

    private static ShadowUtil.MethodListener methodListener;
    private static boolean scanFailed;
    private static ScanResult scanResult;
    private static ScanCallback scanCallback;

    @Resetter
    public static void resetMe() {
        Log.d(TAG, "resetMe");
        methodListener = null;
        scanFailed = false;
        scanResult = null;
        scanCallback = null;
    }

    public static void setMethodListener(ShadowUtil.MethodListener listener) {
        methodListener = listener;
    }

    public static void setScanFailed(boolean scanFailed_) {
        scanFailed = scanFailed_;
    }

    public static void setScanResult(ScanResult scanResult_) {
        scanResult = scanResult_;
    }

    public static void triggerScanResult() {
        if (scanCallback != null) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (scanFailed) {
                        Log.d(TAG, "notify scan failed ...");
                        scanCallback.onScanFailed(ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED);
                    } else if (scanResult != null) {
                        Log.d(TAG, "notify scan result ...");
                        scanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
                    }
                }
            }).start();
        }
    }

    public MyShadowBluetoothLeScanner() {
    }

    public void startScan(ScanCallback callback) {
        throw new RuntimeException("Unexpected!");
    }

    public void startScan(List<ScanFilter> filters, ScanSettings settings, final ScanCallback callback) {
        Log.d(TAG, "startScan with callback ...");
        scanCallback = callback;
        triggerScanResult();
    }

    public int startScan(List<ScanFilter> filters, ScanSettings settings, PendingIntent callbackIntent) {
        Log.d(TAG, "startScan with callback intent ...");
        return 0;
    }

    public void stopScan(ScanCallback callback) {
        Log.d(TAG, "stopScan with callback ...");
        if (methodListener != null) {
            String name = Thread.currentThread().getStackTrace()[1].getMethodName();
            Object[] parameters = { callback };
            methodListener.onCallMethod(name, parameters);
        }
    }

    public void stopScan(PendingIntent callbackIntent) {
        Log.d(TAG, "stopScan with callback intent ...");
        if (methodListener != null) {
            String name = Thread.currentThread().getStackTrace()[1].getMethodName();
            Object[] parameters = { callbackIntent };
            methodListener.onCallMethod(name, parameters);
        }
    }

    public void flushPendingScanResults(ScanCallback callback) {
        throw new RuntimeException("Unexpected!");
    }
}
